package com.laker.monitor.agent.bytebuddy;

import com.laker.monitor.agent.bytebuddy.interceptor.TraceInterceptor;
import com.laker.monitor.agent.bytebuddy.listener.LogListener;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;

import java.lang.instrument.Instrumentation;

import static net.bytebuddy.matcher.ElementMatchers.*;

/**
 * 启动说明，后面的是需要追踪的包路径
 * -javaagent:D:\soft\agent.jar=com.laker.monitor
 */
public class MiniAgent {

    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("※※※※※※※※※※※※※※※※※※※");
        System.out.println("[miniAgent] agentArgs：" + agentArgs);
        System.out.println("※※※※※※※※※※※※※※※※※※※");
        if (agentArgs == null) {
            System.out.println("agentArgs is null, [miniAgent] fail!!!");
            System.out.println("You should configure the package path after agent.jar,");
            System.out.println("for example, agent.jar=com.laker.monitor");
            return;
        }
        new AgentBuilder
                .Default()
                // 指定需要拦截的类
                .type(nameStartsWith(agentArgs)
                        .and(not(isInterface()).and(not(isStatic()))))
                .transform((builder, typeDescription, classLoader) -> builder
                        // 指定需要拦截的方法
                        .method(ElementMatchers.not(isSetter())
                                .and(not(isGetter()))
                                .and(not(isHashCode()))
                                .and(not(isEquals()))
                                // 剔除toString方法
                                .and(not(isToString()))
                                // 剔除main方法
                                .and(not(nameStartsWith("main"))))
                        .intercept(MethodDelegation.to(TraceInterceptor.class)// 委托
                        ))
                .with(LogListener.listener)
                .installOn(inst);
    }
}